```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单点登录限制技术深度解析</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            background-color: #f8fafc;
        }
        .hero {
            background: linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%);
        }
        .code-block {
            background-color: #1e293b;
            color: #e2e8f0;
            border-left: 4px solid #3b82f6;
        }
        .section-card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
        }
        .section-card:hover {
            transform: translateY(-4px);
            box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
        }
        .highlight {
            position: relative;
        }
        .highlight:after {
            content: '';
            position: absolute;
            left: 0;
            bottom: 2px;
            width: 100%;
            height: 8px;
            background-color: rgba(59, 130, 246, 0.2);
            z-index: -1;
            transition: all 0.3s ease;
        }
        .highlight:hover:after {
            height: 16px;
            background-color: rgba(59, 130, 246, 0.3);
        }
    </style>
</head>
<body class="leading-relaxed">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:py-28">
        <div class="max-w-5xl mx-auto text-center">
            <div class="inline-block bg-blue-600/20 px-4 py-2 rounded-full mb-6">
                <span class="text-sm font-medium"><i class="fas fa-lock mr-2"></i>账号安全技术</span>
            </div>
            <h1 class="text-4xl md:text-5xl font-bold mb-6">单点登录限制技术<span class="highlight">深度解析</span></h1>
            <p class="text-xl md:text-2xl max-w-3xl mx-auto opacity-90 mb-10">在数字化时代保障用户账号安全的<strong class="font-semibold">核心解决方案</strong></p>
            <div class="flex flex-wrap justify-center gap-4">
                <div class="bg-white/10 backdrop-blur-sm px-6 py-3 rounded-lg flex items-center">
                    <i class="fas fa-shield-alt mr-2"></i>
                    <span>安全防护</span>
                </div>
                <div class="bg-white/10 backdrop-blur-sm px-6 py-3 rounded-lg flex items-center">
                    <i class="fas fa-mobile-alt mr-2"></i>
                    <span>多设备管理</span>
                </div>
                <div class="bg-white/10 backdrop-blur-sm px-6 py-3 rounded-lg flex items-center">
                    <i class="fas fa-bolt mr-2"></i>
                    <span>性能优化</span>
                </div>
            </div>
        </div>
    </section>

    <!-- Introduction Section -->
    <section class="max-w-5xl mx-auto px-4 py-16">
        <div class="bg-white rounded-xl p-8 shadow-lg">
            <div class="flex items-center mb-6">
                <div class="w-12 h-12 rounded-full bg-blue-50 flex items-center justify-center mr-4">
                    <i class="fas fa-info-circle text-blue-600 text-xl"></i>
                </div>
                <h2 class="text-2xl font-bold text-gray-800">单点登录限制的重要性</h2>
            </div>
            <p class="text-lg text-gray-700 mb-6">在当今数字化时代，用户账号安全已成为每个应用系统的核心关注点。想象一下，如果你的银行账号可以同时在多个设备上登录，你的资金安全将面临怎样的风险？<span class="font-medium">单点登录限制正是解决这一问题的关键技术</span>。</p>
            <div class="bg-blue-50/50 border border-blue-100 rounded-lg p-6">
                <div class="flex">
                    <div class="flex-shrink-0 mr-3">
                        <i class="fas fa-exclamation-triangle text-blue-600 mt-1"></i>
                    </div>
                    <div>
                        <h3 class="font-medium text-gray-800 mb-2">应用场景广泛</h3>
                        <p class="text-gray-700">从电商平台到企业管理系统，从在线教育到金融应用，几乎所有需要用户认证的场景都需要考虑登录限制。这不仅关乎用户体验，更是数据安全的重要保障。</p>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Content Navigation -->
    <section class="max-w-5xl mx-auto px-4 py-8">
        <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
            <a href="#section-1" class="bg-white rounded-lg p-4 text-center hover:bg-blue-50 transition-colors">
                <div class="text-blue-600 mb-2"><i class="fas fa-cogs text-2xl"></i></div>
                <span class="font-medium">核心原理</span>
            </a>
            <a href="#section-2" class="bg-white rounded-lg p-4 text-center hover:bg-blue-50 transition-colors">
                <div class="text-blue-600 mb-2"><i class="fas fa-database text-2xl"></i></div>
                <span class="font-medium">Session方案</span>
            </a>
            <a href="#section-3" class="bg-white rounded-lg p-4 text-center hover:bg-blue-50 transition-colors">
                <div class="text-blue-600 mb-2"><i class="fas fa-key text-2xl"></i></div>
                <span class="font-medium">JWT方案</span>
            </a>
            <a href="#section-4" class="bg-white rounded-lg p-4 text-center hover:bg-blue-50 transition-colors">
                <div class="text-blue-600 mb-2"><i class="fas fa-server text-2xl"></i></div>
                <span class="font-medium">Redis方案</span>
            </a>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-5xl mx-auto px-4 pb-20">
        <!-- Section 1 -->
        <section id="section-1" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-10 h-10 rounded-full bg-blue-600 text-white flex items-center justify-center mr-4">
                    <span class="font-bold">1</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">单点登录限制的核心原理</h2>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <!-- Card 1 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-blue-100 text-blue-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-comments"></i>
                        </div>
                        <h3 class="text-xl font-semibold">会话管理机制</h3>
                    </div>
                    <p class="text-gray-700 mb-4">单点登录限制的核心在于会话管理。当用户登录时，系统会创建一个唯一的会话标识，并将该标识与用户账号绑定。当同一账号在其他地方尝试登录时，系统会检查是否已存在活跃会话。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto mb-4">
                        <pre><code class="text-blue-200">// 会话管理核心逻辑示例
public class SessionManager {
    private Map&lt;String, UserSession&gt; activeSessions = new ConcurrentHashMap&lt;&gt;();
    
    public boolean login(String userId, String sessionId) {
        // 检查是否已存在活跃会话
        UserSession existingSession = activeSessions.get(userId);
        if (existingSession != null) {
            // 强制下线旧会话
            invalidateSession(existingSession.getSessionId());
        }
        
        // 创建新会话
        UserSession newSession = new UserSession(userId, sessionId, System.currentTimeMillis());
        activeSessions.put(userId, newSession);
        return true;
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 2 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-purple-100 text-purple-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-fingerprint"></i>
                        </div>
                        <h3 class="text-xl font-semibold">令牌验证策略</h3>
                    </div>
                    <p class="text-gray-700 mb-4">现代系统通常使用JWT（JSON Web Token）作为身份验证令牌。JWT包含了用户身份信息和过期时间，服务器通过验证令牌的有效性来判断用户登录状态。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto mb-4">
                        <pre><code class="text-blue-200">// JWT令牌验证示例
public class JwtTokenValidator {
    public boolean validateToken(String token, String userId) {
        try {
            Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody();
            
            // 检查用户ID是否匹配
            String tokenUserId = claims.getSubject();
            if (!userId.equals(tokenUserId)) {
                return false;
            }
            
            // 检查令牌是否过期
            Date expiration = claims.getExpiration();
            return !expiration.before(new Date());
        } catch (Exception e) {
            return false;
        }
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 3 -->
                <div class="section-card bg-white rounded-xl p-6 md:col-span-2">
                    <div class="flex items-start mb-4">
                        <div class="bg-green-100 text-green-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-mobile-alt"></i>
                        </div>
                        <h3 class="text-xl font-semibold">设备标识技术</h3>
                    </div>
                    <p class="text-gray-700 mb-4">为了更精确地控制登录限制，系统通常会结合设备标识技术。通过收集设备指纹（如IP地址、User-Agent、设备ID等），可以更准确地识别不同的登录设备。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// 设备标识生成示例
public class DeviceIdentifier {
    public String generateDeviceId(HttpServletRequest request) {
        String ipAddress = getClientIpAddress(request);
        String userAgent = request.getHeader("User-Agent");
        String deviceId = DigestUtils.md5Hex(ipAddress + userAgent);
        return deviceId;
    }
    
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            return xForwardedFor.split(",")[0].trim();
        }
        return request.getRemoteAddr();
    }
}</code></pre>
                    </div>
                </div>

                <!-- Visualization -->
                <div class="md:col-span-2">
                    <div class="bg-white rounded-xl p-6">
                        <h3 class="text-xl font-semibold mb-4 flex items-center">
                            <i class="fas fa-project-diagram text-blue-600 mr-2"></i>
                            <span>单点登录限制工作原理</span>
                        </h3>
                        <div class="mermaid">
                            sequenceDiagram
                                participant User
                                participant Client
                                participant Server
                                participant Database
                                
                                User->>Client: 输入凭据登录
                                Client->>Server: 发送登录请求
                                Server->>Database: 检查现有会话
                                alt 存在活跃会话
                                    Database-->>Server: 返回会话信息
                                    Server->>Database: 使旧会话失效
                                    Server->>Database: 创建新会话
                                else 无活跃会话
                                    Server->>Database: 创建新会话
                                end
                                Server-->>Client: 返回认证成功
                                Client-->>User: 登录成功
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section 2 -->
        <section id="section-2" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-10 h-10 rounded-full bg-blue-600 text-white flex items-center justify-center mr-4">
                    <span class="font-bold">2</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">传统Session方案实现</h2>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <!-- Card 1 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-yellow-100 text-yellow-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-memory"></i>
                        </div>
                        <h3 class="text-xl font-semibold">内存存储方案</h3>
                    </div>
                    <p class="text-gray-700 mb-4">最简单的实现方式是使用内存存储会话信息。这种方式实现简单，但存在单点故障风险，不适合分布式部署。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto mb-4">
                        <pre><code class="text-blue-200">// 内存存储的会话管理器
@Component
public class InMemorySessionManager {
    private final Map&lt;String, SessionInfo&gt; sessions = new ConcurrentHashMap&lt;&gt;();
    
    public void createSession(String userId, String sessionId) {
        SessionInfo sessionInfo = new SessionInfo();
        sessionInfo.setUserId(userId);
        sessionInfo.setSessionId(sessionId);
        sessionInfo.setCreateTime(System.currentTimeMillis());
        sessionInfo.setLastAccessTime(System.currentTimeMillis());
        
        sessions.put(userId, sessionInfo);
    }
    
    public boolean isSessionValid(String userId, String sessionId) {
        SessionInfo sessionInfo = sessions.get(userId);
        return sessionInfo != null && 
               sessionInfo.getSessionId().equals(sessionId) &&
               !isSessionExpired(sessionInfo);
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 2 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-green-100 text-green-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-database"></i>
                        </div>
                        <h3 class="text-xl font-semibold">数据库存储方案</h3>
                    </div>
                    <p class="text-gray-700 mb-4">使用数据库存储会话信息可以解决内存存储的持久化问题，但会增加数据库压力。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto mb-2">
                        <pre><code class="text-blue-200">-- 会话表结构
CREATE TABLE user_sessions (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id VARCHAR(50) NOT NULL,
    session_id VARCHAR(100) NOT NULL,
    device_id VARCHAR(100),
    ip_address VARCHAR(50),
    user_agent TEXT,
    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_access_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_active BOOLEAN DEFAULT TRUE,
    INDEX idx_user_id (user_id),
    INDEX idx_session_id (session_id)
);</code></pre>
                    </div>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto mt-2">
                        <pre><code class="text-blue-200">// 数据库会话管理器
@Service
public class DatabaseSessionManager {
    @Autowired
    private SessionRepository sessionRepository;
    
    public void createSession(String userId, String sessionId, String deviceId) {
        // 先删除该用户的旧会话
        sessionRepository.deleteByUserId(userId);
        
        // 创建新会话
        UserSession session = new UserSession();
        session.setUserId(userId);
        session.setSessionId(sessionId);
        session.setDeviceId(deviceId);
        session.setActive(true);
        
        sessionRepository.save(session);
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 3 -->
                <div class="section-card bg-white rounded-xl p-6 md:col-span-2">
                    <div class="flex items-start mb-4">
                        <div class="bg-red-100 text-red-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-network-wired"></i>
                        </div>
                        <h3 class="text-xl font-semibold">分布式Session管理</h3>
                    </div>
                    <p class="text-gray-700 mb-4">在分布式环境中，可以使用Redis等缓存系统来管理会话，既保证了性能又支持集群部署。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// Redis分布式会话管理器
@Service
public class RedisSessionManager {
    @Autowired
    private RedisTemplate&lt;String, Object&gt; redisTemplate;
    
    private static final String SESSION_KEY_PREFIX = "session:";
    private static final int SESSION_EXPIRE_TIME = 3600; // 1小时
    
    public void createSession(String userId, String sessionId) {
        String key = SESSION_KEY_PREFIX + userId;
        SessionInfo sessionInfo = new SessionInfo(userId, sessionId);
        
        // 使用Redis的原子操作确保单点登录
        redisTemplate.opsForValue().set(key, sessionInfo, SESSION_EXPIRE_TIME, TimeUnit.SECONDS);
    }
    
    public boolean validateSession(String userId, String sessionId) {
        String key = SESSION_KEY_PREFIX + userId;
        SessionInfo sessionInfo = (SessionInfo) redisTemplate.opsForValue().get(key);
        
        return sessionInfo != null && sessionInfo.getSessionId().equals(sessionId);
    }
}</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section 3 -->
        <section id="section-3" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-10 h-10 rounded-full bg-blue-600 text-white flex items-center justify-center mr-4">
                    <span class="font-bold">3</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">现代JWT令牌方案</h2>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <!-- Card 1 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-blue-100 text-blue-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-code"></i>
                        </div>
                        <h3 class="text-xl font-semibold">JWT令牌结构设计</h3>
                    </div>
                    <p class="text-gray-700 mb-4">JWT令牌包含三个部分：头部、载荷和签名。载荷部分可以包含用户ID、设备ID、登录时间等信息。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto mb-4">
                        <pre><code class="text-blue-200">// JWT令牌生成器
@Component
public class JwtTokenGenerator {
    private static final String SECRET_KEY = "your-secret-key";
    private static final long TOKEN_EXPIRE_TIME = 3600 * 1000; // 1小时
    
    public String generateToken(String userId, String deviceId) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + TOKEN_EXPIRE_TIME);
        
        return Jwts.builder()
                .setSubject(userId)
                .claim("deviceId", deviceId)
                .claim("loginTime", now.getTime())
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 2 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-purple-100 text-purple-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-sync-alt"></i>
                        </div>
                        <h3 class="text-xl font-semibold">令牌刷新机制</h3>
                    </div>
                    <p class="text-gray-700 mb-4">为了提供更好的用户体验，系统通常支持令牌刷新机制，允许用户在令牌即将过期时自动刷新。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// 令牌刷新服务
@Service
public class TokenRefreshService {
    @Autowired
    private RedisTemplate&lt;String, Object&gt; redisTemplate;
    
    public String refreshToken(String oldToken, String userId) {
        // 验证旧令牌
        if (!validateToken(oldToken)) {
            throw new InvalidTokenException("无效的令牌");
        }
        
        // 检查是否允许刷新（防止无限刷新）
        String refreshKey = "refresh:" + userId;
        Integer refreshCount = (Integer) redisTemplate.opsForValue().get(refreshKey);
        if (refreshCount != null && refreshCount >= 5) {
            throw new TokenRefreshLimitException("刷新次数超限");
        }
        
        // 生成新令牌
        String newToken = generateNewToken(userId);
        
        // 更新刷新计数
        redisTemplate.opsForValue().increment(refreshKey);
        redisTemplate.expire(refreshKey, 24, TimeUnit.HOURS);
        
        return newToken;
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 3 -->
                <div class="section-card bg-white rounded-xl p-6 md:col-span-2">
                    <div class="flex items-start mb-4">
                        <div class="bg-red-100 text-red-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-ban"></i>
                        </div>
                        <h3 class="text-xl font-semibold">黑名单管理策略</h3>
                    </div>
                    <p class="text-gray-700 mb-4">当用户主动登出或令牌被撤销时，需要将令牌加入黑名单，防止被恶意使用。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// 令牌黑名单管理
@Service
public class TokenBlacklistService {
    @Autowired
    private RedisTemplate&lt;String, Object&gt; redisTemplate;
    
    private static final String BLACKLIST_PREFIX = "blacklist:";
    
    public void addToBlacklist(String token) {
        // 解析令牌获取过期时间
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
        
        Date expiration = claims.getExpiration();
        long ttl = (expiration.getTime() - System.currentTimeMillis()) / 1000;
        
        // 将令牌加入黑名单，过期时间与令牌相同
        String blacklistKey = BLACKLIST_PREFIX + DigestUtils.md5Hex(token);
        redisTemplate.opsForValue().set(blacklistKey, "1", ttl, TimeUnit.SECONDS);
    }
    
    public boolean isBlacklisted(String token) {
        String blacklistKey = BLACKLIST_PREFIX + DigestUtils.md5Hex(token);
        return redisTemplate.hasKey(blacklistKey);
    }
}</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section 4 -->
        <section id="section-4" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-10 h-10 rounded-full bg-blue-600 text-white flex items-center justify-center mr-4">
                    <span class="font-bold">4</span>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">Redis分布式解决方案</h2>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <!-- Card 1 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-indigo-100 text-indigo-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-sitemap"></i>
                        </div>
                        <h3 class="text-xl font-semibold">Redis数据结构设计</h3>
                    </div>
                    <p class="text-gray-700 mb-4">使用Redis实现单点登录限制时，需要合理设计数据结构以支持高效的查询和更新操作。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// Redis数据结构设计
public class RedisSessionData {
    // 用户会话映射：userId -> sessionInfo
    private static final String USER_SESSION_KEY = "user_session:";
    
    // 会话详情：sessionId -> sessionDetails
    private static final String SESSION_DETAIL_KEY = "session_detail:";
    
    // 设备会话映射：deviceId -> sessionId
    private static final String DEVICE_SESSION_KEY = "device_session:";
    
    // 活跃会话列表：用于监控和清理
    private static final String ACTIVE_SESSIONS_KEY = "active_sessions";
}</code></pre>
                    </div>
                </div>

                <!-- Card 2 -->
                <div class="section-card bg-white rounded-xl p-6">
                    <div class="flex items-start mb-4">
                        <div class="bg-pink-100 text-pink-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-clock"></i>
                        </div>
                        <h3 class="text-xl font-semibold">过期策略配置</h3>
                    </div>
                    <p class="text-gray-700 mb-4">Redis支持多种过期策略，可以根据业务需求选择合适的策略。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// Redis过期策略配置
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate&lt;String, Object&gt; redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate&lt;String, Object&gt; template = new RedisTemplate&lt;&gt;();
        template.setConnectionFactory(factory);
        
        // 设置序列化器
        Jackson2JsonRedisSerializer&lt;Object&gt; serializer = new Jackson2JsonRedisSerializer&lt;&gt;(Object.class);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        
        template.afterPropertiesSet();
        return template;
    }
    
    // 配置Redis过期策略
    @Bean
    public RedisCacheConfiguration cacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)) // 默认1小时过期
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
    }
}</code></pre>
                    </div>
                </div>

                <!-- Card 3 -->
                <div class="section-card bg-white rounded-xl p-6 md:col-span-2">
                    <div class="flex items-start mb-4">
                        <div class="bg-yellow-100 text-yellow-800 p-2 rounded-lg mr-4">
                            <i class="fas fa-server"></i>
                        </div>
                        <h3 class="text-xl font-semibold">集群部署考虑</h3>
                    </div>
                    <p class="text-gray-700 mb-4">在Redis集群环境中，需要考虑数据分片和一致性等问题。</p>
                    <div class="code-block rounded-lg p-4 text-sm overflow-x-auto">
                        <pre><code class="text-blue-200">// Redis集群配置
@Configuration
public class RedisClusterConfig {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName("localhost");
        config.setPort(6379);
        config.setPassword("password");
        
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config);
        factory.afterPropertiesSet();
        return factory;
    }
    
    // 配置Redis集群
    @Bean
    public RedisClusterConfiguration redisClusterConfiguration() {
        Set&lt;String&gt; clusterNodes = new HashSet&lt;&gt;();
        clusterNodes.add("192.168.1.10:7000");
        clusterNodes.add("192.168.1.11:7000");
        clusterNodes.add("192.168.1.12:7000");
        
        RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(clusterNodes);
        clusterConfig.setMaxRedirects(3);
        return clusterConfig;
    }
}</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <!-- Visualization Section -->
        <section class="mb-20">
            <div class="bg-white rounded-xl p-8 shadow-lg">
                <h2 class="text-2xl font-bold mb-6 text-center">单点登录限制技术架构演进</h2>
                <div class="mermaid max-w-4xl mx-auto">
                    graph TD
                        A[传统Session方案] -->|简单易用| B(内存存储)
                        A -->|持久化| C(数据库存储)
                        A -->|分布式扩展| D(Redis存储)
                        D --> E[现代JWT方案]
                        E --> F[无状态认证]
                        E --> G[跨域支持]
                        E --> H[微服务友好]
                        D --> I[高性能]
                        D --> J[可扩展]
                </div>
            </div>
        </section>
    </main>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            },
            sequence: {
                diagramMarginX: 50,
                diagramMarginY: 10,
                boxTextMargin: 5,
                noteMargin: 10,
                messageMargin: 35
            }
        });
    </script>
</body>
</html>
```